﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using Xc.DataAccess.Core;
using Xc.DataAccess.HyperTerminalCore.Models;
using System.Threading;
using YamlDotNet.Core.Tokens;
using System.Windows;
using System.Windows.Threading;

namespace Xc.DataAccess.HyperTerminalCore.Services
{
    /// <summary>
    /// TCP服务 
    /// </summary>
    public class TcpServerService :  ITcpServerService
    {
        /// <summary>
        /// TCP客户端列表
        /// </summary>
        public ObservableCollection<TcpClientInfo> TcpClients { get; set; } = new ObservableCollection<TcpClientInfo>();
        TcpListener IDeviceService;
        public Task<Result> OpenAsync(TcpServerOption option)
        {
            return Task.Run(() => {
                try
                {
                    if (IDeviceService != null)
                    {
                        IDeviceService.Stop();
                    }
                    IDeviceService = new TcpListener(IPAddress.Any, option.Port);
                    IDeviceService.Start();
                    ThreadPool.QueueUserWorkItem(new WaitCallback(AcceptClients));
                    Option = option;
                    return Result.Accept("开启成功");

                }
                catch (Exception err)
                {
                    return Result.Reject(err.Message);
                }
            });

        }
        /// <summary>
        /// 线程分发器
        /// </summary>
        public Dispatcher Dispatcher { get; set; }
        public Action<string> ServerMessage;
        CancellationTokenSource Token = new CancellationTokenSource();
        private async void AcceptClients(object state)
        {
            while (!Token.IsCancellationRequested)
            {
                try
                {
                    if (IDeviceService.Pending())
                    {
                        var client = await IDeviceService.AcceptTcpClientAsync();
                        var inf = new TcpClientInfo(client, Option.Encoding);
                        inf.OnClose += async (s) =>
                        {
                            OnClientCloing?.Invoke(s);
                            await Dispatcher?.InvokeAsync(() => {
                                TcpClients.Remove(s);
                            });
                        };
                        await Dispatcher?.InvokeAsync(() => {
                            TcpClients.Add(inf);
                        });
                        inf.BeginRead();
                        OnClientJoin?.Invoke(inf);
                    }
                    else
                    {
                        await Task.Delay(100);
                    }
                }
                catch (Exception err)
                {
                    ServerMessage?.Invoke(err.Message);
                }
            }
        }
        /// <summary>
        /// 客户端接入时触发
        /// </summary>
        public event Action<TcpClientInfo> OnClientJoin;
        public Result Close()
        {
            try
            {
                Token.Cancel();
                IDeviceService.Stop();
                return Result.Accept("关闭成功");

            }
            catch (Exception err)
            {
                return Result.Reject(err.Message);

            }
        }
        public event Action<TcpClientInfo> OnClientCloing;
        public TcpServerOption Option { get; set; }
    }
}
